#include "PlayScene.h"
#include "Board.h"
#include "NetworkManager.h"
#include "GameManager.h"
#include "RoundSummaryView.h"
#include "JsonObject.h"
#include "SoundManager.h"
#include "GameConfig.h"

using std::set;
using std::pair;

USING_NS_CC;

const unsigned int Board_Size = 5;
const unsigned int Letter_Offset = 10;

const int Pos_Offset_In_Row = 60;
const int Pos_Offset_In_Col = 60;

CCLabelTTF* gLabel = NULL;

std::set<LetterTile*> LetterTile::smAllTiles;
std::set<LetterTile*> LetterTile::smSelectedTilesRecord;

CCScene* PlayScene::scene()
{
	// 'scene' is an autorelease object
	CCScene *scene = CCScene::create();

	// 'layer' is an autorelease object
	PlayScene *layer = PlayScene::create();

	// add layer as a child to scene
	scene->addChild(layer);

	// return the scene
	return scene;
}

// on "init" you need to initialize your instance
bool PlayScene::init()
{
	if ( !CCLayer::init() )
	{
		return false;
	}

	CCSize size = CCDirector::sharedDirector()->getWinSize();

	// create menu, it's an autorelease object
	mBoard = new Board();
	mBoard->init();
	mBoard->autorelease();

	mBoard->setPosition( CCPoint(Pos_Offset_In_Row - 20, Pos_Offset_In_Col + 40) );
	this->addChild(mBoard, 1);

	gLabel = CCLabelTTF::create("", "Arial", 20);

	gLabel->setPosition( ccp(size.width / 2, size.height - 50) );
	this->addChild(gLabel, 1);

	mTimeLabel = CCLabelTTF::create("", "Arial", 15);
	mTimeLabel->setPosition( ccp(10, size.height - 70) );
	this->addChild(mTimeLabel, 1);

	return true;
}

void PlayScene::setLayerLetters(unsigned int layerIndex, const std::string& letters)
{
	assert(letters.length() == Board_Size * Board_Size);

	mLayerLetters[layerIndex] = letters;
}

void PlayScene::onEnterTransitionDidFinish()
{
	CCLayer::onEnterTransitionDidFinish();

	SoundManager::getInstance().playEffect(eSoundEffectID_StartGame);

	mTime = (float)RoundSeconds;
	char szBuf[4] = {'\0'};
	sprintf_s(szBuf, "%d", int(mTime));
	mTimeLabel->setString(szBuf);

	assert(mLayerLetters[0].length() == Board_Size * Board_Size);

	// add letters
	for(size_t row = 0; row < Board_Size; row++)
	{
		for(size_t col = 0; col < Board_Size; col++)
		{
			char letter = mLayerLetters[0][row * Board_Size + col];

			LetterTile* pLetterTile = new LetterTile(letter, CCPoint(Pos_Offset_In_Row * row, Pos_Offset_In_Col * col));
			pLetterTile->autorelease();

			mBoard->addChild(pLetterTile);
		}
	}

	scheduleUpdate();
}

void PlayScene::update(float deltaTime)
{
	mTime -= deltaTime;

	char szBuf[4] = {'\0'};
	sprintf_s(szBuf, "%d", int(mTime));

	mTimeLabel->setString(szBuf);

	if(mTime <= 0)
	{
		mTime = 0;

		SoundManager::getInstance().playEffect(eSoundEffectID_EndGame);		

		unscheduleUpdate();

		mBoard->setTouchEnabled(false);

		updateResults();
	}
}

void PlayScene::updateResults()
{
	char szBuff[10] = {"\0"}; 

	Game* game = GameManager::getInstance().getCurrentGame();
	assert(game);

	std::map<std::string, std::string> paraList;
	paraList.insert(std::make_pair("gameCookie", game->gameCookie));
	paraList.insert(std::make_pair("yourCookie", GameManager::getInstance().mPlayerCookie));

	sprintf(szBuff, "%d", game->curRound);
	paraList.insert(std::make_pair("yourRound", szBuff));

	std::vector<std::string>& recordedWords = mBoard->getRecordedWords();
	unsigned int numOfWords = recordedWords.size();
	sprintf(szBuff, "%d", numOfWords);
	paraList.insert(std::make_pair("yourScore", szBuff));

	NetworkManager::getInstance()->call(
		"SendResult"
		,this
		,callfuncO_selector(PlayScene::onUpdateResultsSucceed)
		,callfuncO_selector(PlayScene::onUpdateResultsFailed)
		,&paraList
		);
}

void PlayScene::onUpdateResultsSucceed(CCObject* param)
{
	JsonObject* pJson = dynamic_cast<JsonObject*>(param);
	CCAssert( pJson ,"invalid type!");
	if( pJson )
	{
		Json::Value& jsonval = pJson->getJsonVal();
		int msgType = jsonval["msgType"].asInt();		

		if(msgType == Msg::GameUpdate)
		{
			// switch to roundSummaryView Scene
			CCScene* pScene = new CCScene();
			pScene->autorelease();

			RoundSummaryView* roundSummaryScene = RoundSummaryView::create();

			pScene->addChild(roundSummaryScene);

			CCTransitionFade * transitionScene = CCTransitionFade::create( 1.0f, pScene, ccWHITE );
			CCDirector::sharedDirector()->replaceScene(transitionScene);
		}
	}
}

void PlayScene::onUpdateResultsFailed(CCObject* param)
{
	assert(0);
}